package com.jsz.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jsz.dao.PermissionDao;
import com.jsz.dao.RoleDao;
import com.jsz.dao.UserDao;
import com.jsz.entity.PageResult;
import com.jsz.entity.QueryPageBean;
import com.jsz.pojo.Permission;
import com.jsz.pojo.Role;
import com.jsz.pojo.User;
import com.jsz.service.UserService;
import com.jsz.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@SuppressWarnings("all")
@Service(interfaceClass = UserService.class)
@Transactional
public class UserServiceimpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private PermissionDao permissionDao;

    //根据用户名查询数据库获取用户信息和关联的角色信息，同时需要查询角色关联的权限信息
    @Override
    public User findByUsername(String username) {
        //根据用户名查询用户信息 (不包含角色信息)
        User user = userDao.findByUsername(username);
        if (user == null) {
            //没有查询到用户信息,retrun null 终止代码
            return null;
        }

        //查询到用户信息,获取用户ID值,根据用户ID值到t_user_role中间关系表查询Role角色信息
        Integer userId = user.getId();
        //获取用户对应的角色集合
        Set<Role> roles = roleDao.findBuUserId(userId);
        //遍历角色集合,获取每一个角色信息
        for (Role role : roles) {
            //获取每一个角色的ID
            Integer roleId = role.getId();
            //根据角色ID查询关联的权限,根据role的id去到 t_permission表查询.要通过中间表t_role_permission表查
            Set<Permission> permissions = permissionDao.findByRoleId(roleId);
            //让角色关联对应的权限
            role.setPermissions(permissions);
        }
        //当循环结束时,每个角色都有了对应的权限, 然后在把角色赋值给user用户
        user.setRoles(roles);
        return user;
    }

    //分页查询
    @Override
    public PageResult findByPage(QueryPageBean queryPageBean) {
        //获取当前页
        Integer currentPage = queryPageBean.getCurrentPage();
        //获取总分页套数
        Integer pageSize = queryPageBean.getPageSize();
        //获取查询条件
        String queryString = queryPageBean.getQueryString();

        //调用分页查询件,进行数据分页
        PageHelper.startPage(currentPage, pageSize);
        Page<User> page = userDao.findUserByCondition(queryString);
        List<User> rows = page.getResult();

        long total = page.getTotal();
        return new PageResult(total, rows);
    }

    //添加用户信息
    @Override
    public void addUser(User user, Integer[] roleIds) throws Exception {
        //给用户添加注册用户的时间
        String regTime = DateUtils.parseDate2String(DateUtils.getToday());
        //将注册时间带入User中封存
        user.setRegTime(regTime);

        if (user.getPassword() != null) {
            //处理用户传过来的密码,对用户的密码进行加密
            String ps = user.getPassword();
            //使用工具栏进行加密
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            String password = encoder.encode(ps);
            //将已经加密的密码带入User中封装
            user.setPassword(password);
        }
        //添加用户数据
        userDao.addUser(user);
        //调用下面的方法方法,添加用户关联的角色ID集合
        this.insertUserAndRole(user, roleIds);
    }

    //根据ID查询用户信息
    @Override
    public User findById(Integer id) {
        return userDao.findById(id);
    }

    //根据用户ID查询中间关系表,查询用户对于的角色信息
    @Override
    public List<Integer> findRoleIdsByUserId(Integer id) {
        return userDao.findRoleIdsByUserId(id);
    }

    //编辑用户信息
    @Override
    public void update(User user, Integer[] roleIds) {
        if (user.getPassword().equals("*****")) {
            throw new RuntimeException("密码格式错误,密码格式不能为*****!!!");
        }
        if (user.getPassword() != null) {
            //处理用户传过来的密码,对用户的密码进行加密
            String ps = user.getPassword();
            //使用工具类进行加密
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            String password = encoder.encode(ps);
            //将已经加密的密码带入User中封装
            user.setPassword(password);
        }
        //调用持久成保存数据
        userDao.update(user);
        //删除中间关系表中的关联关系
        userDao.deleteCondition(user.getId());
        //在添加重新勾选的角色ID信息
        this.insertUserAndRole(user, roleIds);
    }

    //删除用户信息
    @Override
    public void deleteUserById(Integer id) {
        //1.根据用户ID删除中间关系表
        userDao.deleteCondition(id);
        //2.在根据ID删除用户信息
        userDao.deleteById(id);
    }

    //通用方法,用于封装用户关联的角色信息
    private void insertUserAndRole(User user, Integer[] roleIds) {
        //定义一个Map集合用于封装数据
        Map<String, Integer> map = new HashMap<>();
        //判断
        if (roleIds != null && roleIds.length > 0) {
            for (Integer roleId : roleIds) {
                //获取每一个角色ID
                map.put("user_id", user.getId());
                map.put("role_id", roleId);
                //调用业务层
                userDao.insertUserAndRole(map);
            }
        }
    }
}
